package com.tomato.dynamic.threadpool.common.enums;

import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

import java.util.Objects;
import java.util.concurrent.*;

/**
 * 队列类型枚举
 *
 * @author lizhifu
 */
@Slf4j
@Getter
public enum QueueTypeEnum {

    /**
     * 队列
     */
    ARRAY_BLOCKING_QUEUE(1,"ArrayBlockingQueue"),

    LINKED_BLOCKING_QUEUE(2,"LinkedBlockingQueue"),

    PRIORITY_BLOCKING_QUEUE(3,"PriorityBlockingQueue"),

    DELAY_QUEUE(4,"DelayQueue"),

    SYNCHRONOUS_QUEUE(5,"SynchronousQueue"),

    LINKED_TRANSFER_QUEUE(6,"LinkedTransferQueue"),
    /**
     * 默认队列
     * 当前执行的线程数量达到corePoolSize的数量时，剩余的元素会在阻塞队列里等待;
     * 当队列满时，才会开启新的线程，立即执行新添加的任务;
     * 当线程数达到 maximumPoolSize 数量时，执行线程拒绝策略。
     */
    LINKED_BLOCKING_DEQUE(7,"LinkedBlockingDeque"),

    VARIABLE_LINKED_BLOCKING_QUEUE(8,"VariableLinkedBlockingQueue");

    private final Integer code;
    private final String name;

    QueueTypeEnum(Integer code, String name) {
        this.code = code;
        this.name = name;
    }

    /**
     * 根据 name 创建队列
     * @param name 队列名称
     * @param capacity 容量
     * @return
     */
    public static BlockingQueue<Runnable> buildBlockingQueue(String name, int capacity) {
        BlockingQueue<Runnable> blockingQueue = null;
        if (Objects.equals(name, ARRAY_BLOCKING_QUEUE.getName())) {
            blockingQueue = new ArrayBlockingQueue<>(capacity);
        } else if (Objects.equals(name, LINKED_BLOCKING_QUEUE.getName())) {
            blockingQueue = new LinkedBlockingQueue<>(capacity);
        } else if (Objects.equals(name, PRIORITY_BLOCKING_QUEUE.getName())) {
            blockingQueue = new PriorityBlockingQueue<>(capacity);
        } else if (Objects.equals(name, DELAY_QUEUE.getName())) {
            blockingQueue = new DelayQueue();
        } else if (Objects.equals(name, SYNCHRONOUS_QUEUE.getName())) {
            blockingQueue = new SynchronousQueue();
        } else if (Objects.equals(name, LINKED_TRANSFER_QUEUE.getName())) {
            blockingQueue = new LinkedTransferQueue<>();
        } else if (Objects.equals(name, LINKED_BLOCKING_DEQUE.getName())) {
            blockingQueue = new LinkedBlockingDeque<>(capacity);
        } else if (Objects.equals(name, VARIABLE_LINKED_BLOCKING_QUEUE.getName())) {
           // TODO 容量可修改队列
        }
        if (blockingQueue == null) {
            log.info("错误的队列类型 BlockingQueue {}，使用默认队列 LINKED_BLOCKING_QUEUE", name);
            blockingQueue = new LinkedBlockingDeque<>(capacity);
        }
        log.info("创建队列 {},容量 {}", name, capacity);
        return blockingQueue;
    }
}
